package com.lwl.java8.chapter7;

import org.junit.Test;

import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Chapter7Test {

    // 测量对前n个自然数求和的函数的性能
    public long measureSumPerf(Function<Long, Long> adder, long n) {
        long fastest = Long.MAX_VALUE;
        long sum = 0;
        for (int i = 0; i < 10; i++) {
            long start = System.nanoTime();
            sum = adder.apply(n);
            long duration = (System.nanoTime() - start) / 1_000_000;
            if (duration < fastest)
                fastest = duration;
        }
        System.out.println("sum=" + sum);
        return fastest;
    }

    // 一个迭代式字数统计方法
    public int countWordsIteratively(String str) {
        // aaa aa aavc
        int counter = 0;
        boolean lastSpace = true;
        for (char c : str.toCharArray()) {
            if (Character.isWhitespace(c)) {
                lastSpace = true;
            } else {
                if (lastSpace)
                    counter++;
                lastSpace = false;
            }
        }
        return counter;
    }

    @Test
    public void test1() {

        // 141 msecs
		/*
		 * System.out.println("Sequential sum done in:" +
		 * measureSumPerf(ParallelStreams::sequentialSum, 10_000_000) + " msecs"
		 * );
		 */
        // 387 msecs
		/*
		 * System.out.println("Parallel sum done in:" +
		 * measureSumPerf(ParallelStreams::parallelSum, 10_000_000) + " msecs");
		 */
        // 6 msecs
		/*
		 * System.out.println("Ranged sum done in:" +
		 * measureSumPerf(ParallelStreams::rangedSum, 10_000_000) + " msecs");
		 */

        // 3 msecs
		/*
		 * System.out.println("Parallel ranged sum done in:" +
		 * measureSumPerf(ParallelStreams::parallelRangedSum, 10_000_000) +
		 * " msecs");
		 */

        // 串行 72 msecs
		/*
		 * System.out.println("SideEffect ranged sum done in:" +
		 * measureSumPerf(ParallelStreams::sideEffectSum, 10_000_000) + " msecs"
		 * );
		 */
        // 错误的使用并行,得到错误的结果
		/*
		 * System.out.println("SideEffectParallelSum ranged sum done in:" +
		 * measureSumPerf(ParallelStreams::sideEffectParallelSum, 10_000_000) +
		 * " msecs");
		 */
        // 44 msecs
        System.out
                .println("forkJoin sum done in:" + measureSumPerf(ParallelStreams::forkJoinSum, 10_000_000) + " msecs");

    }

    @Test
    public void test2() {
        String SENTENCE = " Nel mezzo del cammin di nostra vita " + "mi ritrovai in una selva oscura"
                + " ché la  dritta via era smarrita ";
        System.out.println("Found " + countWordsIteratively(SENTENCE) + " words");
    }

    @Test
    public void test3() {

        String SENTENCE = " Nel mezzo del cammin di nostra vita " + "mi ritrovai in una selva oscura"
                + " ché la  dritta via era smarrita ";

        Stream<Character> stream = IntStream.range(0, SENTENCE.length()).mapToObj(SENTENCE::charAt);

    }

    private int countWords(Stream<Character> stream) {
        WordCounter wordCounter = stream.reduce(new WordCounter(0, true),
                WordCounter::accumulate,
                WordCounter::combine);
        return wordCounter.getCounter();
    }


    @Test
    public void test4() {
        String SENTENCE = " Nel mezzo del cammin di nostra vita " + "mi ritrovai in una selva oscura"
                + " ché la  dritta via era smarrita ";

        Stream<Character> stream = IntStream.range(0, SENTENCE.length())
                .mapToObj(SENTENCE::charAt);
        System.out.println("Found " + countWords(stream) + " words");
    }

    interface Task{
        public void execute();
    }

    public static void doSomething(Runnable r){
        r.run();
    }

    public static void doSomething(Task r){
        System.out.println("task ...");
        r.execute();
    }

    @Test
    public void test5() {
        doSomething((Task)() -> System.out.println("Danger Task!!"));
        //doSomething((Runnable)() -> System.out.println("Danger Runnable!!"));

    }


}
